home *** CD-ROM | disk | FTP | other *** search
- /* DelayLine.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "DelayLine.h"
- #include "Memory.h"
- #include "DelayEffectSpec.h"
-
-
- /* tap algorithm select */
- typedef enum
- {
- eTapLeftToLeftNoFilter EXECUTE(= -3241),
- eTapLeftToMonoNoFilter,
- eTapLeftToRightNoFilter,
- eTapMonoToLeftNoFilter,
- eTapMonoToMonoNoFilter,
- eTapMonoToRightNoFilter,
- eTapRightToLeftNoFilter,
- eTapRightToMonoNoFilter,
- eTapRightToRightNoFilter,
- eTapLeftToLeftAverageFilter,
- eTapLeftToMonoAverageFilter,
- eTapLeftToRightAverageFilter,
- eTapMonoToLeftAverageFilter,
- eTapMonoToMonoAverageFilter,
- eTapMonoToRightAverageFilter,
- eTapRightToLeftAverageFilter,
- eTapRightToMonoAverageFilter,
- eTapRightToRightAverageFilter
- } TapAlgorithm;
-
-
- typedef struct DelayLineTapRec
- {
- /* link to next tap record */
- struct DelayLineTapRec* Next;
-
- /* what are we tapping */
- DelayChannelType SourceTap;
- float SourceTime;
- float SourceTimeAccent1Adjust;
- float SourceTimeAccent2Adjust;
- float SourceTimeAccent3Adjust;
- float SourceTimeAccent4Adjust;
- DelayChannelType TargetTap;
- float TargetTime;
- float TargetTimeAccent1Adjust;
- float TargetTimeAccent2Adjust;
- float TargetTimeAccent3Adjust;
- float TargetTimeAccent4Adjust;
- float ScaleFactor;
- float ScaleFactorAccent1Adjust;
- float ScaleFactorAccent2Adjust;
- float ScaleFactorAccent3Adjust;
- float ScaleFactorAccent4Adjust;
-
- /* lowpass filter control */
- DelayFilterType EnableFilter;
-
- /* control information */
- TapAlgorithm TapProcessAlgorithm;
-
- /* state information */
- long SourceOffset;
- long TargetOffset;
- float Scaling;
- largefixedsigned MovingAverageFilterState;
- } DelayLineTapRec;
-
-
- struct DelayLineRec
- {
- /* maximum delay */
- float MaxDelayTime;
-
- /* state information */
- long DelayLineLength; /* must be power of 2 */
- long DelayLineIndex;
- largefixedsigned* LeftDelayLineArray; /* for mono, only this one is used */
- largefixedsigned* RightDelayLineArray;
- long FramesPerSecond;
-
- /* tap list */
- DelayLineTapRec* Taps;
-
- /* free list link */
- DelayLineRec* Next;
- };
-
-
- static DelayLineRec* DelayLineFreeList = NIL;
- static DelayLineTapRec* DelayLineTapFreeList = NIL;
-
-
- /* flush cached delay line records */
- void FlushCachedDelayLineStuff(void)
- {
- while (DelayLineFreeList != NIL)
- {
- DelayLineRec* Temp;
-
- Temp = DelayLineFreeList;
- DelayLineFreeList = DelayLineFreeList->Next;
- ReleasePtr((char*)Temp);
- }
- while (DelayLineTapFreeList != NIL)
- {
- DelayLineTapRec* Temp;
-
- Temp = DelayLineTapFreeList;
- DelayLineTapFreeList = DelayLineTapFreeList->Next;
- ReleasePtr((char*)Temp);
- }
- }
-
-
- /* create a new delay line processor */
- DelayLineRec* NewDelayLineProcessor(struct DelayEffectRec* Template,
- long FramesPerSecond)
- {
- DelayLineRec* Delay;
- long Temp;
- long Scan;
- long Limit;
- DelayLineTapRec* Appender;
-
- CheckPtrExistence(Template);
- if (DelayLineFreeList != NIL)
- {
- Delay = DelayLineFreeList;
- DelayLineFreeList = DelayLineFreeList->Next;
- }
- else
- {
- Delay = (DelayLineRec*)AllocPtrCanFail(sizeof(DelayLineRec),"DelayLineRec");
- if (Delay == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- }
-
- Delay->MaxDelayTime = GetDelayMaxTime(Template);
- Delay->Taps = NIL;
-
- /* set line length */
- Temp = FramesPerSecond * Delay->MaxDelayTime + 1;
- Temp = Temp & 0x3fffffff;
- Delay->DelayLineLength = 1UL;
- while (Temp != 0)
- {
- Temp = Temp >> 1;
- Delay->DelayLineLength = Delay->DelayLineLength << 1;
- }
- Delay->FramesPerSecond = FramesPerSecond;
- Delay->DelayLineIndex = 0;
-
- /* build lines */
- Delay->LeftDelayLineArray = (largefixedsigned*)AllocPtrCanFail(
- sizeof(largefixedsigned) * Delay->DelayLineLength,"DelayLineArray");
- if (Delay->LeftDelayLineArray == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)Delay);
- goto FailurePoint1;
- }
- Delay->RightDelayLineArray = (largefixedsigned*)AllocPtrCanFail(
- sizeof(largefixedsigned) * Delay->DelayLineLength,"DelayLineArray");
- if (Delay->RightDelayLineArray == NIL)
- {
- FailurePoint3:
- ReleasePtr((char*)Delay->LeftDelayLineArray);
- goto FailurePoint2;
- }
- for (Temp = 0; Temp < Delay->DelayLineLength; Temp += 1)
- {
- Delay->LeftDelayLineArray[Temp] = 0;
- Delay->RightDelayLineArray[Temp] = 0;
- }
-
- /* build tap list */
- Appender = NIL;
- Limit = GetDelayEffectSpecNumTaps(Template);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- DelayLineTapRec* Tap;
-
- /* allocate delay line */
- if (DelayLineTapFreeList != NIL)
- {
- Tap = DelayLineTapFreeList;
- DelayLineTapFreeList = DelayLineTapFreeList->Next;
- }
- else
- {
- Tap = (DelayLineTapRec*)AllocPtrCanFail(sizeof(DelayLineTapRec),"DelayLineTapRec");
- if (Tap == NIL)
- {
- FailurePoint4:
- while (Delay->Taps != NIL)
- {
- Tap = Delay->Taps;
- Delay->Taps = Delay->Taps->Next;
- ReleasePtr((char*)Tap);
- }
- ReleasePtr((char*)Delay->RightDelayLineArray);
- goto FailurePoint3;
- }
- }
- /* append to list */
- Tap->Next = NIL;
- if (Appender == NIL)
- {
- Delay->Taps = Tap;
- }
- else
- {
- Appender->Next = Tap;
- }
- Appender = Tap;
- /* fill in template fields */
- Tap->SourceTap = GetDelayTapSource(Template,Scan);
- Tap->SourceTime = GetDelayTapSourceTime(Template,Scan);
- Tap->SourceTimeAccent1Adjust = GetDelayTapSourceTimeAccent1(Template,Scan);
- Tap->SourceTimeAccent2Adjust = GetDelayTapSourceTimeAccent2(Template,Scan);
- Tap->SourceTimeAccent3Adjust = GetDelayTapSourceTimeAccent3(Template,Scan);
- Tap->SourceTimeAccent4Adjust = GetDelayTapSourceTimeAccent4(Template,Scan);
- Tap->TargetTap = GetDelayTapTarget(Template,Scan);
- Tap->TargetTime = GetDelayTapTargetTime(Template,Scan);
- Tap->TargetTimeAccent1Adjust = GetDelayTapTargetTimeAccent1(Template,Scan);
- Tap->TargetTimeAccent2Adjust = GetDelayTapTargetTimeAccent2(Template,Scan);
- Tap->TargetTimeAccent3Adjust = GetDelayTapTargetTimeAccent3(Template,Scan);
- Tap->TargetTimeAccent4Adjust = GetDelayTapTargetTimeAccent4(Template,Scan);
- Tap->ScaleFactor = GetDelayTapScale(Template,Scan);
- Tap->ScaleFactorAccent1Adjust = GetDelayTapScaleAccent1(Template,Scan);
- Tap->ScaleFactorAccent2Adjust = GetDelayTapScaleAccent2(Template,Scan);
- Tap->ScaleFactorAccent3Adjust = GetDelayTapScaleAccent3(Template,Scan);
- Tap->ScaleFactorAccent4Adjust = GetDelayTapScaleAccent4(Template,Scan);
- Tap->EnableFilter = GetDelayTapFilterType(Template,Scan);
- /* initialize state variables */
- Tap->MovingAverageFilterState = 0;
- /* determine which algorithm to use */
- switch (Tap->SourceTap)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad tap source"));
- break;
- case eTapLeftChannel:
- switch (Tap->TargetTap)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad tap target"));
- break;
- case eTapLeftChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapLeftToLeftNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapLeftToLeftAverageFilter;
- break;
- }
- break;
- case eTapRightChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapLeftToRightNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapLeftToRightAverageFilter;
- break;
- }
- break;
- case eTapMonoChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapLeftToMonoNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapLeftToMonoAverageFilter;
- break;
- }
- break;
- }
- break;
- case eTapRightChannel:
- switch (Tap->TargetTap)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad tap target"));
- break;
- case eTapLeftChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapRightToLeftNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapRightToLeftAverageFilter;
- break;
- }
- break;
- case eTapRightChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapRightToRightNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapRightToRightAverageFilter;
- break;
- }
- break;
- case eTapMonoChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapRightToMonoNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapRightToMonoAverageFilter;
- break;
- }
- break;
- }
- break;
- case eTapMonoChannel:
- switch (Tap->TargetTap)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad tap target"));
- break;
- case eTapLeftChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapMonoToLeftNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapMonoToLeftAverageFilter;
- break;
- }
- break;
- case eTapRightChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapMonoToRightNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapMonoToRightAverageFilter;
- break;
- }
- break;
- case eTapMonoChannel:
- switch (Tap->EnableFilter)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewDelayLineProcessor: bad filter"));
- break;
- case eTapNoFilter:
- Tap->TapProcessAlgorithm = eTapMonoToMonoNoFilter;
- break;
- case eTapMovingAverageLP:
- Tap->TapProcessAlgorithm = eTapMonoToMonoAverageFilter;
- break;
- }
- break;
- }
- break;
- }
- }
-
- return Delay;
- }
-
-
- /* dispose of the delay line processor */
- void DisposeDelayLineProcessor(DelayLineRec* Delay)
- {
- CheckPtrExistence(Delay);
- ReleasePtr((char*)Delay->LeftDelayLineArray);
- ReleasePtr((char*)Delay->RightDelayLineArray);
- while (Delay->Taps != NIL)
- {
- DelayLineTapRec* Temp;
-
- Temp = Delay->Taps;
- Delay->Taps = Delay->Taps->Next;
- Temp->Next = DelayLineTapFreeList;
- DelayLineTapFreeList = Temp;
- }
- Delay->Next = DelayLineFreeList;
- DelayLineFreeList = Delay;
- }
-
-
- /* update delay line state with accent information */
- void UpdateDelayLineState(DelayLineRec* Delay, float Accent1, float Accent2,
- float Accent3, float Accent4)
- {
- DelayLineTapRec* Scan;
-
- CheckPtrExistence(Delay);
- /* update tap states */
- Scan = Delay->Taps;
- while (Scan != NIL)
- {
- float Time;
-
- /* determine source offset */
- Time = Scan->SourceTime + Accent1 * Scan->SourceTimeAccent1Adjust
- + Accent2 * Scan->SourceTimeAccent2Adjust + Accent3
- * Scan->SourceTimeAccent3Adjust + Accent4 * Scan->SourceTimeAccent4Adjust;
- if (Time < 0)
- {
- Time = 0;
- }
- if (Time > Delay->MaxDelayTime)
- {
- Time = Delay->MaxDelayTime;
- }
- Scan->SourceOffset = Time * Delay->FramesPerSecond;
- /* determine target offset */
- Time = Scan->TargetTime + Accent1 * Scan->TargetTimeAccent1Adjust
- + Accent2 * Scan->TargetTimeAccent2Adjust + Accent3
- * Scan->TargetTimeAccent3Adjust + Accent4 * Scan->TargetTimeAccent4Adjust;
- if (Time < 0)
- {
- Time = 0;
- }
- if (Time > Delay->MaxDelayTime)
- {
- Time = Delay->MaxDelayTime;
- }
- Scan->TargetOffset = Time * Delay->FramesPerSecond;
- /* determine scale factor */
- Scan->Scaling = Scan->ScaleFactor + Accent1 * Scan->ScaleFactorAccent1Adjust
- + Accent2 * Scan->ScaleFactorAccent2Adjust + Accent3
- * Scan->ScaleFactorAccent3Adjust + Accent4 * Scan->ScaleFactorAccent4Adjust;
- /* do the next one */
- Scan = Scan->Next;
- }
- }
-
-
- /* apply delay processing to some stuff to stereo data */
- void ApplyDelayLineStereo(largefixedsigned* Data, long NumFrames,
- DelayLineRec* Delay)
- {
- long Scan;
- long VectorMask;
- long VectorIndex;
- largefixedsigned* LeftDelayLineArray;
- largefixedsigned* RightDelayLineArray;
-
- CheckPtrExistence(Data);
- CheckPtrExistence(Delay);
- VectorMask = Delay->DelayLineLength - 1;
- VectorIndex = Delay->DelayLineIndex;
- LeftDelayLineArray = Delay->LeftDelayLineArray;
- RightDelayLineArray = Delay->RightDelayLineArray;
- for (Scan = 0; Scan < NumFrames; Scan += 1)
- {
- DelayLineTapRec* Tap;
-
- /* initialize current point with dry data */
- LeftDelayLineArray[VectorIndex] = Data[Scan * 2 + 0];
- RightDelayLineArray[VectorIndex] = Data[Scan * 2 + 1];
- /* iterate over taps */
- Tap = Delay->Taps;
- while (Tap != NIL)
- {
- long SourceIndex;
- long TargetIndex;
- largefixedsigned Temp;
- largefixedsigned Temp2;
-
- /* precompute some stuff */
- SourceIndex = VectorMask & (VectorIndex + Tap->SourceOffset);
- TargetIndex = VectorMask & (VectorIndex + Tap->TargetOffset);
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[SourceIndex]),
- sizeof(LeftDelayLineArray[SourceIndex]));
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[TargetIndex]),
- sizeof(LeftDelayLineArray[TargetIndex]));
- PRNGCHK(RightDelayLineArray,&(RightDelayLineArray[SourceIndex]),
- sizeof(RightDelayLineArray[SourceIndex]));
- PRNGCHK(RightDelayLineArray,&(RightDelayLineArray[TargetIndex]),
- sizeof(RightDelayLineArray[TargetIndex]));
- /* apply transformation */
- switch (Tap->TapProcessAlgorithm)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "ApplyDelayLineStereo: unknown tap processing algorithm"));
- break;
- case eTapLeftToLeftNoFilter:
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(
- LeftDelayLineArray[SourceIndex] * Tap->Scaling);
- break;
- case eTapLeftToMonoNoFilter:
- Temp = LeftDelayLineArray[SourceIndex] * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp;
- RightDelayLineArray[TargetIndex] += Temp;
- break;
- case eTapLeftToRightNoFilter:
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(
- LeftDelayLineArray[SourceIndex] * Tap->Scaling);
- break;
- case eTapMonoToLeftNoFilter:
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(
- ((LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1) * Tap->Scaling);
- break;
- case eTapMonoToMonoNoFilter:
- Temp = ((LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1) * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp;
- RightDelayLineArray[TargetIndex] += Temp;
- break;
- case eTapMonoToRightNoFilter:
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(
- ((LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1) * Tap->Scaling);
- break;
- case eTapRightToLeftNoFilter:
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(
- RightDelayLineArray[SourceIndex] * Tap->Scaling);
- break;
- case eTapRightToMonoNoFilter:
- Temp = RightDelayLineArray[SourceIndex] * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp;
- RightDelayLineArray[TargetIndex] += Temp;
- break;
- case eTapRightToRightNoFilter:
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(
- RightDelayLineArray[SourceIndex] * Tap->Scaling);
- break;
- case eTapLeftToLeftAverageFilter:
- Temp = LeftDelayLineArray[SourceIndex];
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapLeftToMonoAverageFilter:
- Temp = LeftDelayLineArray[SourceIndex];
- Temp2 = ((Temp + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp2;
- RightDelayLineArray[TargetIndex] += Temp2;
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapLeftToRightAverageFilter:
- Temp = LeftDelayLineArray[SourceIndex];
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapMonoToLeftAverageFilter:
- Temp = (LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1;
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapMonoToMonoAverageFilter:
- Temp = (LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1;
- Temp2 = ((Temp + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp2;
- RightDelayLineArray[TargetIndex] += Temp2;
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapMonoToRightAverageFilter:
- Temp = (LeftDelayLineArray[SourceIndex]
- + RightDelayLineArray[SourceIndex]) >> 1;
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapRightToLeftAverageFilter:
- Temp = RightDelayLineArray[SourceIndex];
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapRightToMonoAverageFilter:
- Temp = RightDelayLineArray[SourceIndex];
- Temp2 = ((Temp + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling;
- LeftDelayLineArray[TargetIndex] += Temp2;
- RightDelayLineArray[TargetIndex] += Temp2;
- Tap->MovingAverageFilterState = Temp;
- break;
- case eTapRightToRightAverageFilter:
- Temp = RightDelayLineArray[SourceIndex];
- RightDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- }
- /* do the next one */
- Tap = Tap->Next;
- }
- /* perform data update */
- PRNGCHK(Data,&(Data[Scan * 2 + 0]),sizeof(Data[Scan * 2 + 0]));
- PRNGCHK(Data,&(Data[Scan * 2 + 1]),sizeof(Data[Scan * 2 + 1]));
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[VectorIndex]),
- sizeof(LeftDelayLineArray[VectorIndex]));
- PRNGCHK(RightDelayLineArray,&(RightDelayLineArray[VectorIndex]),
- sizeof(RightDelayLineArray[VectorIndex]));
- Data[Scan * 2 + 0] = LeftDelayLineArray[VectorIndex];
- Data[Scan * 2 + 1] = RightDelayLineArray[VectorIndex];
- /* increment index */
- VectorIndex = (VectorIndex - 1) & VectorMask;
- }
- Delay->DelayLineIndex = VectorIndex;
- }
-
-
- /* apply delay processing to some stuff to mono data */
- void ApplyDelayLineMono(largefixedsigned* Data, long NumFrames,
- DelayLineRec* Delay)
- {
- long Scan;
- long VectorMask;
- long VectorIndex;
- largefixedsigned* LeftDelayLineArray;
-
- CheckPtrExistence(Data);
- CheckPtrExistence(Delay);
- VectorMask = Delay->DelayLineLength - 1;
- VectorIndex = Delay->DelayLineIndex;
- LeftDelayLineArray = Delay->LeftDelayLineArray;
- for (Scan = 0; Scan < NumFrames; Scan += 1)
- {
- DelayLineTapRec* Tap;
-
- /* clear current output point */
- LeftDelayLineArray[VectorIndex] = Data[Scan];
- /* iterate over taps */
- Tap = Delay->Taps;
- while (Tap != NIL)
- {
- long SourceIndex;
- long TargetIndex;
- largefixedsigned Temp;
-
- /* precompute some stuff */
- SourceIndex = VectorMask & (VectorIndex + Tap->SourceOffset);
- TargetIndex = VectorMask & (VectorIndex + Tap->TargetOffset);
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[SourceIndex]),
- sizeof(LeftDelayLineArray[SourceIndex]));
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[TargetIndex]),
- sizeof(LeftDelayLineArray[TargetIndex]));
- /* apply transformation */
- switch (Tap->TapProcessAlgorithm)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "ApplyDelayLineMono: unknown tap processing algorithm"));
- break;
- case eTapLeftToLeftNoFilter:
- case eTapLeftToMonoNoFilter:
- case eTapLeftToRightNoFilter:
- case eTapMonoToLeftNoFilter:
- case eTapMonoToMonoNoFilter:
- case eTapMonoToRightNoFilter:
- case eTapRightToLeftNoFilter:
- case eTapRightToMonoNoFilter:
- case eTapRightToRightNoFilter:
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(
- LeftDelayLineArray[SourceIndex] * Tap->Scaling);
- break;
- case eTapLeftToLeftAverageFilter:
- case eTapLeftToMonoAverageFilter:
- case eTapLeftToRightAverageFilter:
- case eTapMonoToLeftAverageFilter:
- case eTapMonoToMonoAverageFilter:
- case eTapMonoToRightAverageFilter:
- case eTapRightToLeftAverageFilter:
- case eTapRightToMonoAverageFilter:
- case eTapRightToRightAverageFilter:
- Temp = LeftDelayLineArray[SourceIndex];
- LeftDelayLineArray[TargetIndex] += (largefixedsigned)(((Temp
- + Tap->MovingAverageFilterState) >> 1) * Tap->Scaling);
- Tap->MovingAverageFilterState = Temp;
- break;
- }
- /* do the next one */
- Tap = Tap->Next;
- }
- /* perform data update */
- PRNGCHK(Data,&(Data[Scan]),sizeof(Data[Scan]));
- PRNGCHK(LeftDelayLineArray,&(LeftDelayLineArray[VectorIndex]),
- sizeof(LeftDelayLineArray[VectorIndex]));
- Data[Scan] = LeftDelayLineArray[VectorIndex];
- /* increment index */
- VectorIndex = (VectorIndex - 1) & VectorMask;
- }
- Delay->DelayLineIndex = VectorIndex;
- }
-